package com.lytoyo.neihanduanzi.aspect;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.lytoyo.neihanduanzi.model.Result;
import com.lytoyo.neihanduanzi.model.user.UserInfo;
import com.lytoyo.neihanduanzi.service.impl.UserServiceImpl;
import com.lytoyo.neihanduanzi.utils.AuthContextHolder;
import com.lytoyo.neihanduanzi.utils.Constant;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

/**
 * Package:com.lytoyo.neihanduanzi.aspect
 *
 * @ClassName:loginAspect
 * @Create:2024/10/18 13:05
 **/
@Component
@Aspect
@Slf4j
public class LoginAspect {

    @Resource
    private RedisTemplate redisTemplate;

    @Resource
    private UserServiceImpl userService;
    //利用spring.io 官方文档

    /**
     * 登录切面类
     *
     * @param joinPoint
     * @param Login
     * @return
     * @throws Throwable
     */
    @Around(value = "execution(* com.lytoyo.neihanduanzi.controller.*.*(..)) && @annotation(Login)")
    public Object Login(ProceedingJoinPoint joinPoint, Login Login) throws Throwable {
        //从spring容器上下文请求对象中获取userId
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        //httpServletRequest.getHeader("token")
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) requestAttributes;
        HttpServletRequest request = servletRequestAttributes.getRequest();
        try {
            Long userId = Long.parseLong(request.getHeader("userId"));
            //@Before()
            //未登录
            if (Login.required() && userId == null) {
                //提示用户登录
                ObjectMapper objectMapper = new ObjectMapper();
                String json = objectMapper.writeValueAsString(Result.fail(-2, "请先登录"));
                return json;
            }
            //已经登录
            if (userId != null) {
                //获取用户信息
                String loginKey = Constant.USER_LOGIN_KEY + userId;
                //强制转换为UserInfo对象
                UserInfo userInfo = (UserInfo) this.redisTemplate.opsForValue().get(loginKey);
                //判断当前userInfo 对象是否为空
                //用户为空
                if(null == userInfo){
                    userInfo = userService.getById(userId);
                    if(null == userInfo){
                        ObjectMapper objectMapper = new ObjectMapper();
                        String json = objectMapper.writeValueAsString(Result.fail(-1, "该用户已不存在"));
                        return json;
                    }
                }
                //缓存数据方便后续操作
                AuthContextHolder.setUserId(userInfo.getId());
            }
            //执行带有注解的方法体
            return joinPoint.proceed();
        } finally {
            //@After()
            AuthContextHolder.removeUserId();
        }
    }
}

